import { defineStore } from "pinia"
import { computed, type ComputedRef, ref } from "vue"
import defaultVariables from "@/stores/theme/default-variable"
import VariableName from "./variable-name"
import type ThemeTypes from "@/model/theme/types"

export const useThemeStore = defineStore(
  "theme",
  () => {
    const variables = ref<ThemeTypes.Variables>(defaultVariables)

    function setVariable<T = any>(key: string, value: T, convert?: (value: T, variable: Map<string, string>) => string) {
      if (convert) {
        variables.value.set(key, convert(value, variables.value))
      } else {
        variables.value.set(key, value as string)
      }
    }

    function getThemeType(dark?: any, light?: any) {
      return computed(() => {
        const type = variables.value.get(VariableName.Theme.type)
        if (type === "dark") {
          return dark || "dark"
        }
        if (type === "light") {
          return light || "light"
        }
        return variables.value.get(VariableName.Theme.value) !== "dark"
          ? light || "light"
          : dark || "dark"
      })
    }

    function getVariableRef<T = any | string | undefined>(
      key: string,
      convert?: (value: string | undefined, variable: Map<string, string>) => T
    ): ComputedRef<T> {
      return computed(() => {
        if (convert) {
          return convert(variables.value.get(key), variables.value)
        }
        return variables.value.get(key) as T
      })
    }

    function getVariable<T = any | string | undefined>(
      key: string,
      convert?: (value: string | undefined, variable: Map<string, string>) => T
    ): T {
      if (convert) {
        return convert(variables.value.get(key), variables.value)
      }
      return variables.value.get(key) as T
    }

    return { variables, getThemeType, getVariable, getVariableRef, setVariable }
  },
  {
    persist: ["variables"]
  }
)

export function sizeToPxNumber(value: string | undefined, variables: Map<string, string>): number {
  if (!value) {
    return 0
  }
  const px2Number = (v: string) => {
    return Number(v.substring(0, v.length - 2).trim())
  }
  if (value.trim().endsWith("px")) {
    return px2Number(value)
  }
  if (value.trim().endsWith("rem")) {
    const rootFontSize = px2Number(variables.get(VariableName.Html.fontSize)!)
    return Number(value.substring(0, value.length - 3).trim()) * rootFontSize
  }
  return 0
}

export function pxNumberToSize(value: number, variable: Map<string, string>): string {
  const px2Number = (v: string) => {
    return Number(v.substring(0, v.length - 2).trim())
  }
  const rootFontSize = px2Number(variable.get(VariableName.Html.fontSize)!)
  return (value / rootFontSize) + "rem"
}
